package com.feshfans.xmpp.client;

import com.feshfans.bridge.RosterBridge;
import com.feshfans.xmpp.XmppConnectionManager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.*;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.List;
import java.util.Set;

public class RosterClient extends AbstractListernerClient {

    private static final Logger Log = LoggerFactory.getLogger(RosterClient.class);

    private static final RosterClient ROSTER_CLIENT = new RosterClient(XmppConnectionManager.acquire());

    public static RosterClient  getInstance(){
        return ROSTER_CLIENT;
    }

    private Roster roster;
    private static RosterBridge rosterBridge = RosterBridge.getInstance();

    RosterClient(XMPPTCPConnection connection) {
        super(connection);
        roster = Roster.getInstanceFor(connection);
        initListener();
    }

    /**
     * 初始化 Roster 的相关监听器
     */
    @Override
    protected void initListener(){
        Log.info("开始初始化监听......");
        roster.addPresenceEventListener(new MyPresenceEventListener());
        roster.addRosterLoadedListener(new MyRosterLoadedListener());
        roster.addSubscribeListener(new MySubscribeListener());
        Log.info("初始化监听完成......");
    }

    /**
     * 获取好友列表，包括在线好友和离线好友
     */
    public Set<RosterEntry> getRoster(){
        Set<RosterEntry> set = roster.getEntries();
        return set;
    }

    /**
     * 获取指定用户的在线状态(one or more device)
     */
    public List<Presence> getPresenceByJid(BareJid jid){
        return roster.getAllPresences(jid);
    }

    /**
     * 订阅好友，即添加好友
     *
     */
    public void subscribeRoster(String username) throws XmppStringprepException, SmackException.NotLoggedInException, InterruptedException, SmackException.NotConnectedException {
        String jid = username+"@firmail.cn";
        roster.sendSubscriptionRequest(JidCreate.bareFrom(jid));
    }

    /**
     * 同意别人的好友请求,如果不同意，则什么都不发送，在上层处理
     * @param to 接收者 jid
     */
    public void subscribedRoster(String to) throws SmackException.NotConnectedException, InterruptedException, XmppStringprepException {
        Presence presence = new Presence(Presence.Type.subscribed);
        presence.setTo(JidCreate.bareFrom(to));
        connection.sendStanza(presence);

    }
    /**
     * 取消订阅好友，即删除好友
     */
    public void unsubRoster(){

    }

    static class MyPresenceEventListener implements PresenceEventListener{

        @Override
        public void presenceAvailable(FullJid address, Presence availablePresence) {
            // 如果是房间会话，则丢弃
            if(availablePresence.getFrom()!=null&&availablePresence.getFrom().toString().contains("@muc")){
                return;
            }
            rosterBridge.handlerPresence(address,availablePresence);
        }

        /**
         * 好友离线监听
         * @param address
         * @param presence
         */
        @Override
        public void presenceUnavailable(FullJid address, Presence presence) {
            rosterBridge.handlerPresence(address,presence);
        }

        @Override
        public void presenceError(Jid address, Presence errorPresence) {
            Log.error("监听出席信息出错, jid:{},xml:{}",address.toString(),errorPresence.toXML().toString());
        }

        @Override
        public void presenceSubscribed(BareJid address, Presence subscribedPresence) {
            Log.info("已成功加好友 {}",address.toString());
        }

        /**
         * 别人从好友列表中删除我，会进入此接口
         * @param address
         * @param unsubscribedPresence
         */
        @Override
        public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
            // 别人删除我，不作处理
            Log.info("已成功删除好友 {}",address.toString());
        }
    }

    static class MyRosterListener implements RosterListener{

        @Override
        public void entriesAdded(Collection<Jid> addresses) {
            System.out.println(1);
        }

        @Override
        public void entriesUpdated(Collection<Jid> addresses) {
            System.out.println(2);
        }

        @Override
        public void entriesDeleted(Collection<Jid> addresses) {
            System.out.println(3);
        }

        @Override
        public void presenceChanged(Presence presence) {
            System.out.println(4);
        }
    }

    static class MySubscribeListener implements SubscribeListener{

        /**
         * 处理别人发的好友请求，接收到好友请求
         * @param from
         * @param subscribeRequest
         * @return 空，即不自动回复，等用户同意后再手工发送
         */
        @Override
        public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) {
            rosterBridge.processSubscribe(from,subscribeRequest);
            return null;
        }
    }

    static class MyRosterLoadedListener implements RosterLoadedListener{

        @Override
        public void onRosterLoaded(Roster roster) {
            //通知客户端，好友加载完毕，可以去展示好友列表
            Log.info("加载好友完成");
        }

        @Override
        public void onRosterLoadingFailed(Exception exception) {
            Log.error("加载好友异常",exception);
        }
    }

}
